home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / xarchie-2.0.9 / support.c < prev    next >
C/C++ Source or Header  |  1995-06-18  |  21KB  |  806 lines

  1. /*
  2.  * Copyright (c) 1989, 1990, 1991 by the University of Washington
  3.  *
  4.  * For copying and distribution information, please see the file
  5.  * <copyright.h>.
  6.  *
  7.  * gf xarchie v2.0 - Sync with archie v1.4.1.
  8.  *             Changed to include stringdefs.h.
  9.  *             Changed to use HAVE_STRSPN from config.h.
  10.  */
  11.  
  12. /*
  13.  * Miscellaneous routines pulled from ~beta/lib/pfs and ~beta/lib/filters
  14.  */
  15.  
  16. #include <copyright.h>
  17. #include <stdio.h>
  18. #include <errno.h>
  19.  
  20. #ifdef VMS
  21. # ifdef WOLLONGONG
  22. #  include "twg$tcp:[netdist.include]netdb.h"
  23. # else /* not Wollongong */
  24. #  ifdef UCX
  25. #   include <netdb.h>
  26. #  else /* Multinet */
  27. #   include "multinet_root:[multinet.include]netdb.h"
  28. #  endif
  29. # endif
  30. # include <vms.h>
  31. #else /* not VMS */
  32. # include <sys/types.h>
  33. # include "config.h"                /* gf */
  34. # include "stringdefs.h"            /* gf */
  35. # ifndef CUTCP
  36. #  include <netdb.h>
  37. # endif
  38. # if !defined(MSDOS) || defined(OS2)
  39. #  include <sys/file.h>
  40. #  include <sys/param.h>
  41. # endif
  42. #endif /* VMS */
  43.  
  44. #include <pfs.h>
  45. #include <pprot.h>
  46. #include <perrno.h>
  47. #include <pcompat.h>
  48. #include <pauthent.h>
  49.  
  50. #include "regex.h"
  51.  
  52. int    pfs_enable = PMAP_ATSIGN;
  53.  
  54. #ifndef FALSE
  55. # define TRUE     1
  56. # define FALSE   0
  57. #endif
  58.  
  59. /* 
  60.  * wcmatch - Match string s against template containing widlcards
  61.  *
  62.  *         WCMATCH takes a string and a template, and returns
  63.  *         true if the string matches the template, and 
  64.  *         FALSE otherwise.
  65.  *
  66.  *    ARGS:  s        - string to be tested
  67.  *           template - Template containing optional wildcards
  68.  *
  69.  * RETURNS:  TRUE (non-zero) on match.  FALSE (0) otherwise.
  70.  *
  71.  *    NOTE:  If template is NULL, will return TRUE.
  72.  *
  73.  */
  74. int
  75. wcmatch(s,template)
  76.     char    *s;
  77.     char    *template;
  78.     {
  79.     char    temp[200];
  80.     char    *p = temp;
  81.  
  82.     if(!template) return(TRUE);
  83.     *p++ = '^';
  84.  
  85.     while(*template) {
  86.         if(*template == '*') {*(p++)='.'; *(p++) = *(template++);}
  87.         else if(*template == '?') {*(p++)='.';template++;}
  88.         else if(*template == '.') {*(p++)='\\';*(p++)='.';template++;}
  89.         else if(*template == '[') {*(p++)='\\';*(p++)='[';template++;}
  90.         else if(*template == '$') {*(p++)='\\';*(p++)='$';template++;}
  91.         else if(*template == '^') {*(p++)='\\';*(p++)='^';template++;}
  92.         else if(*template == '\\') {*(p++)='\\';*(p++)='\\';template++;}
  93.         else *(p++) = *(template++);
  94.     }
  95.         
  96.     *p++ = '$';
  97.     *p++ = '\0';
  98.  
  99.     if(re_comp(temp)) return(FALSE);
  100.  
  101. #ifdef AUX
  102.     if (re_exec(s) == (char *)NULL)
  103.       return 0;
  104.     return 1;
  105. #else
  106.     return(re_exec(s));
  107. #endif
  108.     }
  109.  
  110. /*
  111.  * ul_insert - Insert a union link at the right location
  112.  *
  113.  *             UL_INSERT takes a directory and a union link to be added
  114.  *             to a the list of union links in the directory.  It then
  115.  *             inserts the union link in the right spot in the linked
  116.  *             list of union links associated with that directory.
  117.  *
  118.  *           If an identical link already exists, then the link which
  119.  *             would be evaluated earlier (closer to the front of the list)
  120.  *             wins and the other one is freed.  If this happens, an error
  121.  *             will also be returned.
  122.  *        
  123.  *    ARGS:    ul    - link to be inserted
  124.  *           vd    - directory to get link
  125.  *             p     - vl that this link will apper after
  126.  *                     NULL - This vl will go at end of list
  127.  *                     vd   - This vl will go at head of list
  128.  *
  129.  * RETURNS:    Success, or UL_INSERT_ALREADY_THERE or UL_INSERT_SUPERSEDING
  130.  */
  131. int
  132. ul_insert(ul,vd,p)
  133.     VLINK    ul;        /* Link to be inserted                   */
  134.     PVDIR    vd;        /* Directory to receive link             */
  135.     VLINK    p;        /* Union link to appear prior to new one */
  136.     {
  137.     VLINK    current;
  138.  
  139.     /* This is the first ul in the directory */
  140.     if(vd->ulinks == NULL) {
  141.         vd->ulinks = ul;
  142.         ul->previous = NULL;
  143.         ul->next = NULL;
  144.         return(PSUCCESS);
  145.     }
  146.  
  147.     /* This ul will go at the head of the list */
  148.     if(p == (VLINK) vd) {
  149.         ul->next = vd->ulinks;
  150.         ul->next->previous = ul;
  151.         vd->ulinks = ul;
  152.         ul->previous = NULL;
  153.     }
  154.     /* Otherwise, decide if it must be inserted at all  */
  155.     /* If an identical link appears before the position */
  156.     /* at which the new one is to be inserted, we can   */
  157.     /* return without inserting it                 */
  158.     else {
  159.         current = vd->ulinks;
  160.  
  161.         while(current) {
  162.         /* p == NULL means we insert after last link */
  163.         if(!p && (current->next == NULL))
  164.             p = current;
  165.  
  166.         if(vl_comp(current,ul) == 0) {
  167.             vlfree(ul);
  168.             return(UL_INSERT_ALREADY_THERE);
  169.         }
  170.  
  171.         if(current == p) break;
  172.         current = current->next;
  173.         }
  174.  
  175.         /* If current is null, p was not found */
  176.         if(current == NULL)
  177.         return(UL_INSERT_POS_NOTFOUND);
  178.  
  179.         /* Insert ul */
  180.         ul->next = p->next;
  181.         p->next = ul;
  182.         ul->previous = p;
  183.         if(ul->next) ul->next->previous = ul;
  184.     }
  185.  
  186.     /* Check for identical links after ul */
  187.     current = ul->next;
  188.  
  189.     while(current) {
  190.         if(vl_comp(current,ul) == 0) {
  191.         current->previous->next = current->next;
  192.         if(current->next)
  193.             current->next->previous = current->previous;
  194.         vlfree(current);
  195.         return(UL_INSERT_SUPERSEDING);
  196.         }
  197.         current = current->next;
  198.     }
  199.     
  200.     return(PSUCCESS);
  201.     }
  202.  
  203. /*
  204.  * vl_insert - Insert a directory link at the right location
  205.  *
  206.  *             VL_INSERT takes a directory and a link to be added to a 
  207.  *             directory and inserts it in the linked list of links for
  208.  *             that directory.  
  209.  *
  210.  *             If a link already exists with the same name, and if the
  211.  *             information associated with the new link matches that in
  212.  *             the existing link, an error is returned.  If the information
  213.  *             associated with the new link is different, but the magic numbers
  214.  *             match, then the new link will be added as a replica of the
  215.  *             existing link.  If the magic numbers do not match, the new
  216.  *             link will only be added to the list of "replicas" if the
  217.  *             allow_conflict flag has been set.
  218.  * 
  219.  *             If the link is not added, an error is returned and the link
  220.  *             is freed.  Ordering for the list of links is by the link name.  
  221.  *        
  222.  *             If vl is a union link, then VL_INSERT calls ul_insert with an
  223.  *           added argument indicating the link is to be included at the
  224.  *             end of the union link list.
  225.  * 
  226.  *    ARGS:    vl - Link to be inserted, vd - directory to get link
  227.  *             allow_conflict - insert links with conflicting names
  228.  *
  229.  * RETURNS:    Success, or VL_INSERT_ALREADY_THERE
  230.  */
  231. int
  232. vl_insert(vl,vd,allow_conflict)
  233.     VLINK    vl;        /* Link to be inserted               */
  234.     PVDIR    vd;        /* Directory to receive link         */
  235.     int        allow_conflict;    /* Allow duplicate names             */
  236.     {
  237.     VLINK    current;    /* To step through list             */
  238.     VLINK    crep;        /* To step through list of replicas  */
  239.     int    retval;        /* Temp for checking returned values */
  240.  
  241.     /* This can also be used to insert union links at end of list */
  242.     if(vl->linktype == 'U') return(ul_insert(vl,vd,NULL));
  243.  
  244.     /* If this is the first link in the directory */
  245.     if(vd->links == NULL) {
  246.         vd->links = vl;
  247.         vl->previous = NULL;
  248.         vl->next = NULL;
  249.         vd->lastlink = vl;
  250.         return(PSUCCESS);
  251.     }
  252.  
  253.     /* If no sorting is to be done, just insert at end of list */
  254.     if(allow_conflict == VLI_NOSORT) {
  255.         vd->lastlink->next = vl;
  256.         vl->previous = vd->lastlink;
  257.         vl->next = NULL;
  258.         vd->lastlink = vl;
  259.         return(PSUCCESS);
  260.     }
  261.  
  262.     /* If it is to be inserted at start of list */
  263.     if(vl_comp(vl,vd->links) < 0) {
  264.         vl->next = vd->links;
  265.         vl->previous = NULL;
  266.         vl->next->previous = vl;
  267.         vd->links = vl;
  268.         return(PSUCCESS);
  269.     }
  270.  
  271.     current = vd->links;
  272.  
  273.     /* Otherwise, we must find the right spot to insert it */
  274.     while((retval = vl_comp(vl,current)) > 0) {
  275.         if(!current->next) {
  276.         /* insert at end */
  277.         vl->previous = current;
  278.         vl->next = NULL;
  279.         current->next = vl;
  280.         vd->lastlink = vl;
  281.         return(PSUCCESS);
  282.         }
  283.         current = current->next;
  284.     }
  285.  
  286.     /* If we found an equivilant entry already in list */
  287.     if(!retval) {
  288.         if(vl_equal(vl,current)) {
  289.         vlfree(vl);
  290.         return(VL_INSERT_ALREADY_THERE);
  291.         }
  292.         if((allow_conflict == VLI_NOCONFLICT) &&
  293.            ((vl->f_magic_no != current->f_magic_no) ||
  294.         (vl->f_magic_no==0)))
  295.         return(VL_INSERT_CONFLICT);
  296.         /* Insert the link into the list of "replicas" */
  297.         /* If magic is 0, then create a pseudo magic number */
  298.         if(vl->f_magic_no == 0) vl->f_magic_no = -1;
  299.         crep = current->replicas;
  300.         if(!crep) {
  301.         current->replicas = vl;
  302.         vl->next = NULL;
  303.         vl->previous = NULL;
  304.         }
  305.         else {
  306.         while(crep->next) {
  307.             /* If magic was 0, then we need a unique magic number */
  308.             if((crep->f_magic_no < 0) && (vl->f_magic_no < 1))
  309.             (vl->f_magic_no)--;
  310.             crep = crep->next;
  311.         }
  312.         /* If magic was 0, then we need a unique magic number */
  313.         if((crep->f_magic_no < 0) && (vl->f_magic_no < 1))
  314.             (vl->f_magic_no)--;
  315.         crep->next = vl;
  316.         vl->previous = crep;
  317.         vl->next = NULL;
  318.         }
  319.         return(PSUCCESS);
  320.     }
  321.  
  322.     /* We found the spot where vl is to be inserted */
  323.     vl->next = current;
  324.     vl->previous = current->previous;
  325.     current->previous = vl;
  326.     vl->previous->next = vl;
  327.     return(PSUCCESS);
  328.     }
  329.  
  330. /*
  331.  * nlsindex - Find first instance of string 2 in string 1 following newline
  332.  *
  333.  *          NLSINDEX scans string 1 for the first instance of string
  334.  *          2 that immediately follows a newline.  If found, NLSINDEX
  335.  *          returns a pointer to the first character of that instance.
  336.  *          If no instance is found, NLSINDEX returns NULL (0).
  337.  *
  338.  *    NOTE:   This function is only useful for searching strings that
  339.  *            consist of multiple lines.  s1 is assumed to be preceeded
  340.  *           by a newline.  Thus, if s2 is at the start of s1, it will
  341.  *          be found.
  342.  *    ARGS:   s1 - string to be searched
  343.  *            s2 - string to be found
  344.  * RETURNS:   First instance of s2 in s1, or NULL (0) if not found
  345.  */
  346. char *
  347. nlsindex(s1,s2)
  348.     char    *s1;        /* String to be searched */
  349.     char    *s2;        /* String to be found    */
  350.     {
  351.     register int s2len = strlen(s2);
  352.     char    *curline = s1;    /* Pointer to start of current line */
  353.  
  354.     /* In case s2 appears at start of s1 */
  355.     if(strncmp(curline,s2,s2len) == 0)
  356.         return(curline);
  357.  
  358.     /* Check remaining lines of s1 */
  359.     while((curline = (char *) index(curline,'\n')) != NULL) {
  360.         curline++;
  361.         if(strncmp(curline,s2,s2len) == 0)
  362.         return(curline);
  363.     }
  364.  
  365.     /* We didn't find it */
  366.     return(NULL);
  367.     }
  368.  
  369. /*
  370.  * month_sname - Return a month name from it's number
  371.  *
  372.  *               MONTH_SNAME takes a number in the range 0
  373.  *               to 12 and returns a pointer to a string
  374.  *               representing the three letter abbreviation
  375.  *             for that month.  If the argument is out of 
  376.  *         range, MONTH_SNAME returns a pointer to "Unk".
  377.  *
  378.  *       ARGS:   n - Number of the month
  379.  *    RETURNS:   Abbreviation for selected month
  380.  */
  381. char *month_sname(n)
  382.     int n;        /* Month number */
  383. {
  384.     static char *name[] = { "Unk",
  385.         "Jan","Feb","Mar","Apr","May","Jun",
  386.         "Jul","Aug","Sep","Oct","Nov","Dec"
  387.     };
  388.     return((n < 1 || n > 12) ? name[0] : name[n]);
  389. }
  390.  
  391. /*
  392.  * sindex - Find first instance of string 2 in string 1 
  393.  *
  394.  *          SINDEX scans string 1 for the first instance of string
  395.  *          2.  If found, SINDEX returns a pointer to the first
  396.  *          character of that instance.  If no instance is found, 
  397.  *          SINDEX returns NULL (0).
  398.  *
  399.  *    ARGS:   s1 - string to be searched
  400.  *            s2 - string to be found
  401.  * RETURNS:   First instance of s2 in s1, or NULL (0) if not found
  402.  */
  403. char *
  404. sindex(s1,s2)
  405.     char    *s1;        /* String to be searched   */
  406.     char    *s2;        /* String to be found      */
  407.     {
  408.     register int s2len = strlen(s2);
  409.     char    *s = s1;    /* Temp pointer to string  */
  410.  
  411.     /* Check for first character of s2 */
  412.     while((s = (char *) index(s,*s2)) != NULL) {
  413.         if(strncmp(s,s2,s2len) == 0)
  414.         return(s);
  415.         s++;
  416.     }
  417.  
  418.     /* We didn't find it */
  419.     return(NULL);
  420.     }
  421.  
  422. int
  423. scan_error(erst)
  424.     char    *erst;
  425.     {
  426.     *p_err_string = '\0';
  427.  
  428.     if(strncmp(erst,"NOT-A-DIRECTORY",15) == 0) 
  429.         return(DIRSRV_NOT_DIRECTORY);
  430.  
  431.     if(strncmp(erst,"UNIMPLEMENTED",13) == 0) {
  432.         perrno = DIRSRV_UNIMPLEMENTED;
  433.         sscanf(erst+13,"%*[^\n \t\r]%*[ \t]%[^\n]",p_err_string);
  434.         return(perrno);
  435.     }
  436.  
  437.     if(strncmp(erst,"WARNING ",8) == 0) {
  438.         erst += 8;
  439.         *p_warn_string = '\0';
  440.         sscanf(erst,"%*[^\n \t\r]%*[ \t]%[^\n]",p_warn_string);
  441.         /* Return values for warnings are negative */
  442.         if(strncmp(erst,"OUT-OF-DATE",11) == 0) {
  443.         pwarn = PWARN_OUT_OF_DATE;
  444.         return(PSUCCESS);
  445.         }
  446.         if(strncmp(erst,"MESSAGE",7) == 0) {
  447.         pwarn = PWARN_MSG_FROM_SERVER;
  448.         return(PSUCCESS);
  449.         }
  450.         pwarn = PWARNING;
  451.         sscanf(erst,"%[^\n]",p_warn_string);
  452.         return(PSUCCESS);
  453.     }
  454.     else if(strncmp(erst,"ERROR",5) == 0) {
  455.         if(*(erst+5)) sscanf(erst+6,"%[^\n]",p_err_string);
  456.         perrno = DIRSRV_ERROR;
  457.         return(perrno);
  458.     }
  459.     /* The rest start with "FAILURE" */
  460.     else if(strncmp(erst,"FAILURE",7) != 0) {
  461.         /* Unrecognized - Give warning, but return PSUCCESS */
  462.         if(pwarn == 0) {
  463.         *p_warn_string = '\0';
  464.         pwarn = PWARN_UNRECOGNIZED_RESP;
  465.         sscanf(erst,"%[^\n]",p_warn_string);
  466.         }
  467.         return(PSUCCESS);
  468.     }
  469.  
  470.     if(strncmp(erst,"FAILURE ",8) != 0) {
  471.         perrno = PFAILURE;
  472.         return(perrno);
  473.     }    
  474.     erst += 8;
  475.     
  476.     sscanf(erst,"%*[^\n \t\r]%*[ \t]%[^\n]",p_err_string);
  477.  
  478.     /* Still to add               */
  479.     /* DIRSRV_AUTHENT_REQ     242 */
  480.     /* DIRSRV_BAD_VERS        245 */
  481.  
  482.     if(strncmp(erst,"NOT-FOUND",9) == 0) 
  483.         perrno = DIRSRV_NOT_FOUND;
  484.     else if(strncmp(erst,"NOT-AUTHORIZED",13) == 0) 
  485.         perrno = DIRSRV_NOT_AUTHORIZED;
  486.     else if(strncmp(erst,"ALREADY-EXISTS",14) == 0) 
  487.         perrno = DIRSRV_ALREADY_EXISTS;
  488.     else if(strncmp(erst,"NAME-CONFLICT",13) == 0) 
  489.         perrno = DIRSRV_NAME_CONFLICT;
  490.     else if(strncmp(erst,"SERVER-FAILED",13) == 0) 
  491.         perrno = DIRSRV_SERVER_FAILED;
  492.      /* Use it whether it starts with FAILURE or not */
  493.     else if(strncmp(erst,"NOT-A-DIRECTORY",15) == 0) 
  494.         perrno = DIRSRV_NOT_DIRECTORY;
  495.     else perrno = PFAILURE;
  496.  
  497.     return(perrno);
  498.     }
  499.  
  500. PATTRIB 
  501. parse_attribute(line)
  502.     char    *line;
  503.     {
  504.     char    l_precedence[MAX_DIR_LINESIZE];
  505.     char    l_name[MAX_DIR_LINESIZE];
  506.     char    l_type[MAX_DIR_LINESIZE];
  507.     char    l_value[MAX_DIR_LINESIZE];
  508.     PATTRIB    at;
  509.     int    tmp;
  510.  
  511.     tmp = sscanf(line,"OBJECT-INFO %s %s %[^\n]", l_name, l_type, l_value);
  512.     
  513.     if(tmp < 3) {
  514.         tmp = sscanf(line,"LINK-INFO %s %s %s %[^\n]", l_precedence,
  515.              l_name, l_type, l_value);
  516.         if(tmp < 4) {
  517.         perrno = DIRSRV_BAD_FORMAT;
  518.         return(NULL);
  519.         }
  520.     }
  521.  
  522.     at = atalloc();
  523.  
  524.     if(tmp == 4) {
  525.         if(strcmp(l_precedence,"CACHED") == 0) 
  526.         at->precedence = ATR_PREC_CACHED;
  527.         else if(strcmp(l_precedence,"LINK") == 0) 
  528.         at->precedence = ATR_PREC_LINK;
  529.         else if(strcmp(l_precedence,"REPLACEMENT") == 0) 
  530.         at->precedence = ATR_PREC_REPLACE;
  531.         else if(strcmp(l_precedence,"ADDITIONAL") == 0) 
  532.         at->precedence = ATR_PREC_ADD;
  533.     }
  534.  
  535.     at->aname = stcopy(l_name);
  536.     at->avtype = stcopy(l_type);
  537.     if(strcmp(l_type,"ASCII") == 0) 
  538.         at->value.ascii = stcopy(l_value);
  539.     else if(strcmp(l_type,"LINK") == 0) {
  540.         char        ftype[MAX_DIR_LINESIZE];
  541.         char        lname[MAX_DIR_LINESIZE];
  542.         char        htype[MAX_DIR_LINESIZE];
  543.         char        host[MAX_DIR_LINESIZE];
  544.         char        ntype[MAX_DIR_LINESIZE];
  545.         char        fname[MAX_DIR_LINESIZE];
  546.         VLINK        al;
  547.  
  548.         al = vlalloc();
  549.         at->value.link = al;
  550.  
  551.         tmp = sscanf(l_value,"%c %s %s %s %s %s %s %d %d",
  552.              &(al->linktype),
  553.              ftype,lname,htype,host,ntype,fname,
  554.              &(al->version),
  555.              &(al->f_magic_no));
  556.         if(tmp == 9) {
  557.         al->type = stcopyr(ftype,al->type);
  558.         al->name = stcopyr(unquote(lname),al->name);
  559.         al->hosttype = stcopyr(htype,al->hosttype);
  560.         al->host = stcopyr(host,al->host);
  561.         al->nametype = stcopyr(ntype,al->nametype);
  562.         al->filename = stcopyr(fname,al->filename);
  563.         }
  564.         else {
  565.         perrno = DIRSRV_BAD_FORMAT;
  566.         return(NULL);
  567.         }
  568.         
  569.     }
  570.  
  571.     return(at);
  572.     }
  573.  
  574. /*
  575.  * nxtline - Find the next line in the string
  576.  *
  577.  *          NXTLINE takes a string and returns a pointer to
  578.  *          the character immediately following the next newline.
  579.  *
  580.  *    ARGS:   s - string to be searched
  581.  *
  582.  * RETURNS:   Next line or NULL (0) on failure
  583.  */
  584. char *
  585. nxtline(s)
  586.     char    *s;        /* String to be searched */
  587.  {
  588.     s = (char *) index(s,'\n');
  589.     if(s) return(++s);
  590.     else return(NULL);
  591.     }
  592.  
  593.  
  594. /*
  595.  * unquote - unquote string if necessary
  596.  *
  597.  *          UNQUOTE takes a string and unquotes it if it has been quoted.
  598.  *
  599.  *    ARGS:   s - string to be unquoted
  600.  *            
  601.  * RETURNS:   The original string.  If the string has been quoted, then the
  602.  *            result appears in static storage, and must be copied if 
  603.  *            it is to last beyond the next call to quote.
  604.  *
  605.  */
  606. char *
  607. unquote(s)
  608.     char    *s;        /* String to be quoted */
  609.     {
  610.     static char    unquoted[200];
  611.     char        *c = unquoted;
  612.  
  613.     if(*s != '\'') return(s);
  614.  
  615.     s++;
  616.  
  617.     /* This should really treat a quote followed by other */
  618.     /* than a quote or a null as an error                 */
  619.     while(*s) {
  620.         if(*s == '\'') s++;
  621.         if(*s) *c++ = *s++;
  622.     }
  623.  
  624.     *c++ = '\0';
  625.  
  626.     return(unquoted);
  627.     }
  628.  
  629. #if defined(DEBUG) && !defined(HAVE_STRSPN)
  630. /* needed for -D option parsing */
  631. /*
  632.  * strspn - Count initial characters from chrs in s
  633.  *
  634.  *          STRSPN counts the occurances of chacters from chrs
  635.  *            in the string s preceeding the first occurance of
  636.  *            a character not in s.
  637.  *
  638.  *    ARGS:   s    - string to be checked
  639.  *            chrs - string of characters we are looking for
  640.  *
  641.  * RETURNS:   Count of initial characters from chrs in s
  642.  */
  643. strspn(s,chrs)
  644.     char    *s;    /* String to search                         */
  645.     char    *chrs; /* String of characters we are looking for  */
  646.     {
  647.     char    *cp;   /* Pointer to the current character in chrs */
  648.     int    count; /* Count of characters seen so far          */
  649.     
  650.     count = 0;
  651.  
  652.     while(*s) {
  653.         for(cp = chrs;*cp;cp++)
  654.         if(*cp == *s) {
  655.             s++;
  656.             count++;
  657.             goto done;
  658.         }
  659.         return(count);
  660.     done:
  661.         ;
  662.     }
  663.     return(count);
  664.     }
  665. #endif
  666.  
  667. #ifdef CUTCP
  668. char
  669. *inet_ntoa(struct in_addr in)
  670. {
  671.     static    char    buff[36];
  672.  
  673.     unsigned char    *c = (char *) &in.address;
  674.     sprintf(buff,"%d.%d.%d.%d",*c,*(c+1),*(c+2),*(c+3));
  675.     return(buff);
  676. }
  677.  
  678. long
  679. inet_addr(char *cp)
  680. {
  681.     long    value = 0;
  682.     unsigned    v1,v2,v3,v4;
  683.  
  684.     v1 = v2 = v3 = v4 = 0xff;
  685.     sscanf(cp,"%d.%d.%d.%d",&v1,&v2,&v3,&v4);
  686.     value = (v1 << 24) | (v2 << 16) | (v3 << 8) | v4;
  687.     return(value);
  688. }
  689.  
  690. struct    hostent
  691. *gethostbyname(char *name)
  692. {
  693.     struct machinfo    *mp;
  694.     int    mnum;
  695.     unsigned long    now;
  696.     static    struct hostent    ht;
  697.     extern int pfs_debug;
  698.  
  699.     mp = Shostlook(name);
  700.     if(!mp || (!mp->hostip[0])) {    /* DNS lookup */
  701. #ifdef DEBUG
  702.         if (pfs_debug)
  703.         fprintf(stderr, "Domain name lookup of %s\n", name);
  704. #endif
  705.         mnum = Sdomain(name);        /* start a DNS lookup */
  706.         now = time(NULL) + NS_TIMEOUT;
  707.         while(now > time(NULL)) {
  708.             int    i, class, dat;
  709.  
  710.             Stask();
  711.             i = Sgetevent(USERCLASS, &class, &dat);
  712.             if(i == DOMOK) {    /* domain lookup ok */
  713.                 mp = Slooknum(mnum);
  714. #ifdef DEBUG
  715.         if (pfs_debug)
  716.         fprintf(stderr, "Domain name lookup of %s Completed OK\n", name);
  717. #endif
  718.                 break;
  719.             }
  720.         }
  721.         if(!mp)    {    /* get here if timeout */
  722. #ifdef DEBUG
  723.         if (pfs_debug)
  724.         fprintf(stderr, "Domain name lookup of %s Failed\n", name);
  725. #endif
  726.             return(NULL);
  727.         }
  728.     }
  729.     ht.h_addr = *((unsigned long *) mp->hostip);
  730.     ht.h_length = 4;
  731.     ht.h_addrtype = AF_INET;
  732.     return(&ht);
  733.  
  734. }
  735. #endif /* CUTCP */
  736.  
  737. #ifdef GETENV
  738. /*
  739.  * Copyright (c) 1987 Regents of the University of California.
  740.  * All rights reserved.
  741.  *
  742.  * Redistribution and use in source and binary forms are permitted
  743.  * provided that: (1) source distributions retain this entire copyright
  744.  * notice and comment, and (2) distributions including binaries display
  745.  * the following acknowledgement:  ``This product includes software
  746.  * developed by the University of California, Berkeley and its contributors''
  747.  * in the documentation or other materials provided with the distribution
  748.  * and in all advertising materials mentioning features or use of this
  749.  * software. Neither the name of the University nor the names of its
  750.  * contributors may be used to endorse or promote products derived
  751.  * from this software without specific prior written permission.
  752.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  753.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  754.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  755.  */
  756.  
  757. #if defined(LIBC_SCCS) && !defined(lint)
  758. static char sccsid[] = "@(#)getenv.c    5.7 (Berkeley) 6/1/90";
  759. #endif /* LIBC_SCCS and not lint */
  760.  
  761. #include <stdlib.h>
  762. #include <stddef.h>
  763.  
  764. /*
  765.  * getenv --
  766.  *    Returns ptr to value associated with name, if any, else NULL.
  767.  */
  768. char *
  769. getenv(name)
  770.     char *name;
  771. {
  772.     int offset;
  773.     char *_findenv();
  774.  
  775.     return(_findenv(name, &offset));
  776. }
  777.  
  778. /*
  779.  * _findenv --
  780.  *    Returns pointer to value associated with name, if any, else NULL.
  781.  *    Sets offset to be the offset of the name/value combination in the
  782.  *    environmental array, for use by setenv(3) and unsetenv(3).
  783.  *    Explicitly removes '=' in argument name.
  784.  *
  785.  *    This routine *should* be a static; don't use it.
  786.  */
  787. char *
  788. _findenv(name, offset)
  789.     register char *name;
  790.     int *offset;
  791. {
  792.     extern char **environ;
  793.     register int len;
  794.     register char **P, *C;
  795.  
  796.     for (C = name, len = 0; *C && *C != '='; ++C, ++len);
  797.     for (P = environ; *P; ++P)
  798.         if (!strncmp(*P, name, len))
  799.             if (*(C = *P + len) == '=') {
  800.                 *offset = P - environ;
  801.                 return(++C);
  802.             }
  803.     return(NULL);
  804. }
  805. #endif
  806.